/*******************************************************************************
 * Copyright (c) 2011 TXT e-solutions SpA
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * This work was performed within the IoT_at_Work Project
 * and partially funded by the European Commission's
 * 7th Framework Programme under the research area ICT-2009.1.3
 * Internet of Things and enterprise environments.
 *
 *
 * Authors:
 *     Cristoforo Seccia (TXT e-solutions SpA)
 *
 * Contributors:
 *      Domenico Rotondi (TXT e-solutions SpA)
 *******************************************************************************/
package it.txt.access.capability.wizard.panel.controller;

import it.txt.access.capability.factory.values.CapabilityAction;
import it.txt.access.capability.factory.CapabilitySchemaFactoryException;
import it.txt.access.capability.factory.CapabilitySchemaFactory;
import it.txt.access.capability.factory.values.CapabilityValues;
import it.txt.access.capability.commons.signer.model.X509CertificateSubjectInfo;
import it.txt.access.capability.wizard.Wizard;
import it.txt.access.capability.wizard.WizardPanelController;
import it.txt.access.capability.wizard.panel.PanelAccessTypeCapability;
import it.txt.access.capability.wizard.panel.exception.PanelAccessTypeCapabilityException;
import it.txt.access.capability.schema.AccessRightType;
import it.txt.access.capability.schema.AccessRightsCapabilityType;
import java.awt.Component;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;
import javax.swing.JOptionPane;

/**
 *
 * @author Cristoforo Seccia (TXT e-solutions SpA)
 */
public class ControllerPanelAccessTypeCapability extends WizardPanelController {

    private PanelAccessTypeCapability panelAccessTypeCapability;

    public ControllerPanelAccessTypeCapability(Wizard wizard) {
        super(wizard);
        panelAccessTypeCapability = new PanelAccessTypeCapability(getWizard(), this);
    }

    @Override
    public Component getPanelComponent() {
        return panelAccessTypeCapability;
    }

    @Override
    public boolean aboutToDisplayPanel() {
        if (getBackwardObject() == null) {
            return false;
        }
        if(!(getBackwardObject() instanceof AccessRightsCapabilityType)){
            return false;
        }
        AccessRightsCapabilityType capability = (AccessRightsCapabilityType)getBackwardObject();
        fillAccessRightsCapabilityForm(capability);
        return true;
    }

    @Override
    public void displayingPanel() {
        getWizard().setBackButtonEnabled(true);
        getWizard().setNextButtonEnabled(true);
        getWizard().setFinishButtonEnabled(false);
        getWizard().setCancelButtonEnabled(true);
        getWizard().setAccessRightsCreationPercentage(50);
    }

    @Override
    public boolean aboutToHidePanel() {
        try {
            if (panelAccessTypeCapability.checkFormValidity()) {
                AccessRightsCapabilityType capability = (AccessRightsCapabilityType) getBackwardObject();
                setForwardObject(createAccessRightsCapability(capability));
                return true;
            }
        } catch (PanelAccessTypeCapabilityException ex) {
            JOptionPane.showMessageDialog(getWizard(),
                    ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }
        return false;
    }

    private AccessRightsCapabilityType createAccessRightsCapability(AccessRightsCapabilityType innerCapability) throws PanelAccessTypeCapabilityException {
        CapabilityValues capabilityValues = new CapabilityValues();
        capabilityValues.setPolicyAssignee(panelAccessTypeCapability.getAssigneeText());
        capabilityValues.setCapabilityActions(panelAccessTypeCapability.getCapabilityActions());
        capabilityValues.setPolicyNotBeforeDate(panelAccessTypeCapability.getNotBeforeDate());
        capabilityValues.setPolicyNotBeforeTime(panelAccessTypeCapability.getNotBeforeTime());
        capabilityValues.setPolicyNotOrOnAfterDate(panelAccessTypeCapability.getNotOrOnAfterDate());
        capabilityValues.setPolicyNotOrOnAfterTime(panelAccessTypeCapability.getNotOrOnAfterTime());
        String x509IssuerDN = panelAccessTypeCapability.getX509IssuerName().trim().replace(" ", "");
        String x509SerialNumberStr = panelAccessTypeCapability.getX509SerialNumber().trim().replace(" ", "");
        if(!x509IssuerDN.isEmpty() && !x509SerialNumberStr.isEmpty()){
            BigInteger x509SerialNumber = getSubjectSerialNumberAsBigInteger(x509SerialNumberStr);
            X509CertificateSubjectInfo x509SubjectInfo = new X509CertificateSubjectInfo();
            x509SubjectInfo.setX509IssuerName(x509IssuerDN);
            x509SubjectInfo.setX509SerialNumber(x509SerialNumber);
            capabilityValues.setX509SubjectInfo(x509SubjectInfo);
        }        
        try {
            return CapabilitySchemaFactory.getInstance().createAccessRights(innerCapability, capabilityValues);
        } catch (CapabilitySchemaFactoryException ex) {
            throw new PanelAccessTypeCapabilityException(ex.getMessage(), ex);
        }
    }

    private void fillAccessRightsCapabilityForm(AccessRightsCapabilityType innerCapability){
        panelAccessTypeCapability.setIssuerText(innerCapability.getSubject().getSubjectID().getValue());
        panelAccessTypeCapability.setPolicyResourceIDText(innerCapability.getResourceID());
        panelAccessTypeCapability.setPolicyRevocationServices(
                innerCapability.getAccessRightsCapabilityRevocationService().getRevocationServiceEndPoint());
        Date minSelectableDate = innerCapability.getValidityCondition().getNotBefore().toGregorianCalendar().getTime();
        Date maxSelectableDate = innerCapability.getValidityCondition().getNotOnOrAfter().toGregorianCalendar().getTime();
        panelAccessTypeCapability.setMinSelectableDate(minSelectableDate);
        panelAccessTypeCapability.setMaxSelectableDate(maxSelectableDate);
        List<AccessRightType> arts = innerCapability.getAccessRights().getAccessRight();
        panelAccessTypeCapability.resetCapabilityActions();
        for (AccessRightType accessRightType : arts) {
            if (accessRightType.getDelegable().isValue()) {
                CapabilityAction action = new CapabilityAction();
                action.setValue(accessRightType.getPermittedAction().getValue());
                action.setAuthorize(Boolean.FALSE);
                action.setDelegable(Boolean.FALSE);
                panelAccessTypeCapability.addCapabilityAction(action);
            }
        }       
    }

    private BigInteger getSubjectSerialNumberAsBigInteger(String subjectSerialNumberStr) throws PanelAccessTypeCapabilityException{
        try {
            return new BigInteger(subjectSerialNumberStr, 16);
        } catch (Exception ex) {
            throw new PanelAccessTypeCapabilityException(ex.getMessage(), ex);
        }        
    }
}
